package xyz.fefine;

import java.util.HashMap;
import java.util.Map;

/**
 * 记录全局变量名与保存位置之间的关系
 *
 * 存放变量名与它的索引
 *
 * Created by feng_ on 2016/9/17.
 */
public class Symbols {

    /**
     * 记录所在环境的位置(暂时保留)
     */
//    protected int nest;

    /**
     * 位置
     */
    public static class Location {
        public int nest;
        public int index;

        public Location(int nest, int index) {
            this.nest = nest;
            this.index = index;
        }
    }
    protected Symbols outer;
    protected HashMap<String, Integer> table;

    public Symbols() {
        this(null);
    }

    public Symbols(Symbols outer) {
        this.outer = outer;
        this.table = new HashMap<>();
        //暂时预留
/*        if (outer != null) {
            nest = outer.getNest() + 1;
        } else {
            nest = 0;
        }*/
    }

//    public int getNest() {
//        return nest;
//    }

    public int size() {
        return table.size();
    }

    public Location get(String key) {
        return get(key, 0);
    }


    /**
     *
     * @param key 关键字
     * @param nest 环境层
     * @return 位置
     */
    public Location get(String key, int nest) {
        Integer index = table.get(key);
        if (index == null) {
            if (outer == null) {
                return null;
            } else {
                //去上一层寻找,没有的话返回空
                return outer.get(key, nest + 1);
            }
        } else {
            return new Location(nest, index);
        }
    }

    /**
     *  插入新值,返回索引
     * @param key 新值
     * @return 索引
     */
    public int putNew(String key) {
        Integer i = find(key);
        if (i == null) {
            return add(key);
        } else {
            return i;
        }
    }

    /**
     *
     * @param key 关键字
     * @return 索引
     */
    public Integer find(String key) {
        return table.get(key);
    }

    /**
     *
     * @param key 放入的值
     * @return 如果不存在则创建新值,存在的话直接返回位置
     */
    public Location put(String key) {
        //先寻找,没有的话在本层新建
        Location loc = get(key, 0);
        if (loc == null) {
            return new Location(0,add(key));
        } else {
            return loc;
        }
    }

    /**
     * 返回索引
     * @param key 插入的值
     * @return 索引
     */
    public int add(String key) {
        int i = table.size();
        table.put(key, i);
        return i;
    }

    /**
     *
     * @return 测试方法
     */
    public Map getTables() {
        return table;
    }

}
